package org.mybatis.util.base;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

/**
 * @Description 基本工具类
 * @author 米mi
 * @date 2017/08/21 16:43:18
 */
public class Utils {
    
    private static int suffix = 0; // 随机后缀
    
    // -------------------------- 字符串 start --------------------------
    
    /**
     * 获取自定义字符串（表主键）
     * @return 主键
     */
    public static synchronized String getPK(String format) {
        suffix = 0;
        suffix++;
        StringBuffer str = new StringBuffer();
        // 1.添加日期字符串
        String date = formatDate(new Date(), format);
        str.append(date);
        
        // 2.添加后缀（三位数）
        if (suffix > 999) {
            suffix = 0;
        }
        str.append(String.format("%03d", suffix));
        return str.toString();
    }
    
    // -------------------------- 字符串 end --------------------------
    
    // -------------------------- 日期 start --------------------------
    
    /**
     * 日期格式转换（日期-字符串）
     * @param date 日期
     * @param format 日期格式
     * @return 日期字符串
     */
    public static String formatDate(Date date, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(date);
    }
    
    /**
     * 日期格式转换（字符串-日期）
     * @param date 日期字符串
     * @param format 日期格式
     * @return Date 日期
     * @throws ParseException 日期格式转换异常
     */
    public static Date formatString(String date, String format) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.parse(date);
    }
    
    /**
     * @Description 获得日期（一段时间后）
     * @param date 日期
     * @param year 年
     * @param month 月
     * @param day 日
     * @return Date 日期
     */
    public static Date getCalender(Date date, int year, int month, int day) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.YEAR, year); // year年后
        cal.add(Calendar.MONTH, month); // month天后
        cal.add(Calendar.DATE, day); // date天后
        return cal.getTime();
    }
    
    /**
     * @Description 获取时间段
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @param format 日期格式
     * @param sign 分隔符
     * @return 一段日期
     */
    public static String getADate(Date startDate, Date endDate, String format, String sign) {
        
        StringBuffer sbu = new StringBuffer();
        sbu.append(formatDate(startDate, format));
        sbu.append(" " + sign + " ");
        sbu.append(formatDate(endDate, format));
        return sbu.toString();
    }
    
    /**
     * @Description 获取时间段
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @param sign 分隔符
     * @return 时间段
     */
    public static String getADate(Date startDate, Date endDate, String sign) {
        
        StringBuffer sbu = new StringBuffer();
        sbu.append(formatDate(startDate, "yyyy-MM-dd HH:mm:ss"));
        sbu.append(" " + sign + " ");
        sbu.append(formatDate(endDate, "yyyy-MM-dd HH:mm:ss"));
        return sbu.toString();
    }
    
    /**
     * @Description 获取时间段
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @param sign 分隔符
     * @return 时间段
     */
    public static String getADate(String startDate, String endDate, String sign) {
        
        StringBuffer sbu = new StringBuffer();
        sbu.append(startDate);
        sbu.append(" " + sign + " ");
        sbu.append(endDate);
        return sbu.toString();
    }
    
    /**
     * 获取系统当前日期
     * @return 系统当前日期
     */
    public static String getSystemDate() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd EEE HH:mm:ss");
        return sdf.format(new Date());
    }
    
    /**
     * date日期转timestamp时间戳
     * @param date 日期
     * @return Timestamp 时间戳
     */
    public static Timestamp dateToTimestamp(Date date) {
        Timestamp ts = new Timestamp(date.getTime());
        return ts;
    }
    
    // -------------------------- 日期 end --------------------------
    
    // -------------------------- 读取文件 start --------------------------
    
    /**
     * 读取properties配置文件
     * @param url 文件路径
     */
    public static Properties readProperties(String url) {
        Properties properties = new Properties();
        InputStream inputStream = null;
        FileInputStream fileInputStream = null;
        try {
            // 转换路径
            fileInputStream = new FileInputStream(url);
            // 读取属性文件
            inputStream = new BufferedInputStream(fileInputStream);
            properties.load(inputStream);
        }
        catch (FileNotFoundException e1) {
            System.out.println("路径出错了！！！");
            // e1.printStackTrace();
        }
        catch (IOException e) {
            System.out.println("无法读取该文件！！！");
            // e.printStackTrace();
        }
        finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                }
                catch (IOException e) {
                    // e.printStackTrace();
                }
            }
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                }
                catch (IOException e) {
                    // e.printStackTrace();
                }
            }
        }
        return properties;
    }
    
    /**
     * 读取properties配置文件中的value值
     * @param url properties 配置文件的路径
     * @param key properties 配置文件中的key
     */
    public static String readPropertiesValue(String url, String key) {
        // 读取文件
        Properties properties = readProperties(url);
        String result = null;
        
        Iterator<String> it = properties.stringPropertyNames().iterator();
        while (it.hasNext()) {
            String str = it.next();
            if (str.equals(key)) {
                result = properties.getProperty(key).trim();
                break;
            }
        }
        return result;
    }
    
    /**
     * 读取txt文件
     * @param url 文件路径
     * @param encoding 编码格式
     */
    public static List<String> readTxtFile(String url, String encoding) {
        String reader;
        File file;
        InputStreamReader inputStreamReader;
        FileInputStream fileInputStream;
        BufferedReader bufferedReader = null;
        List<String> strings = null;
        try {
            file = new File(url);
            // 判断文件是否存在
            if (file.isFile() && file.exists()) {
                fileInputStream = new FileInputStream(file);
                // 考虑到编码格式
                inputStreamReader = new InputStreamReader(fileInputStream, encoding);
                // 读取文件
                bufferedReader = new BufferedReader(inputStreamReader);
                strings = new ArrayList<>();
                while ((reader = bufferedReader.readLine()) != null) {
                    strings.add(reader);
                }
            }
            else {
                System.out.println("文件不存在！！！");
            }
        }
        catch (FileNotFoundException e) {
            System.out.println("路径出错了！！！");
            // e.printStackTrace();
        }
        catch (UnsupportedEncodingException e) {
            System.out.println("不支持该文件编码！！！");
            // e.printStackTrace();
        }
        catch (IOException e) {
            System.out.println("文件读取出错！！！");
            // e.printStackTrace();
        }
        finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                }
                catch (IOException e) {
                    // e.printStackTrace();
                }
            }
        }
        return strings;
    }
    
    // -------------------------- 读取文件 end --------------------------
    
    // -------------------------- 获取ip地址 start --------------------------
    
    /**
     * @Description 获取ip地址
     * @param url 服务器地址
     * @return ip地址
     * @throws UnknownHostException 抛出异常
     */
    public static String getIpAddress(String url) {
        // 获取的是该网站的ip地址，比如我们所有的请求都通过nginx的，所以这里获取到的其实是nginx服务器的IP地
        InetAddress address = null;
        try {
            address = InetAddress.getByName(url);
        }
        catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            //e.printStackTrace();
        }
        return address.getHostAddress();
    }
    
    /**
     * @Description 获取ip地址
     * @param url 服务器地址
     * @return ip地址
     * @throws UnknownHostException 抛出异常
     */
    public static String[] getIpAddresses(String url) {
        // 根据主机名返回其可能的所有InetAddress对象
        InetAddress[] addresses = null;
        try {
            addresses = InetAddress.getAllByName(url);
        }
        catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        String[] str = new String[addresses.length];
        
        for (InetAddress ine : addresses) {
            int i = 0;
            str[i] = ine.getHostAddress();
            i++;
        }
        return str;
    }
    
    /**
     * @Description 获取ip地址
     * @return ip地址
     * @throws UnknownHostException 抛出异常
     */
    public static String getIpAddress() throws UnknownHostException {
        // 获取的是本地的IP地址
        InetAddress address = InetAddress.getLocalHost();
        return address.getHostAddress();
    }
    
    public static String getIpHostName() throws UnknownHostException {
        InetAddress address = InetAddress.getLocalHost();
        return address.getHostName();
    }
    
    public static InetAddress getIpLocalHost() throws UnknownHostException {
        InetAddress address = InetAddress.getLocalHost();
        return address.getLocalHost();
    }
    
    // -------------------------- 获取ip地址 end --------------------------
    
    // -------------------------- 随机生成 start --------------------------
    
    /**
     * 随机生产字母
     * @return 字母
     */
    public static String getChar() {
        char c = (char) (Math.random() * 26 + 97);
        return String.valueOf(c);
    }
    
    /**
     * 随机生成字符串
     * @param size 字符串大小
     * @return 字符串
     */
    public static String getString(int size) {
        StringBuffer str = new StringBuffer();
        for (int i = 0; i < size; i++) {
            // 将随机生成的字母添加到str中
            str.append(getChar());
        }
        return str.toString();
    }
    
    /**
     * 随机生成汉字
     * @return 汉字
     */
    public static String getCharacters() {
        char c = (char) (0x4e00 + (Math.random() * (0x9fa5 - 0x4e00 + 1)));
        return String.valueOf(c);
    }
    
    /**
     * 随机生成汉字字符串 2017/08/21 18:33:01
     * @param size 字符串大小
     * @return 汉字字符串
     */
    public static String getChinese(int size) {
        StringBuffer str = new StringBuffer();
        for (int i = 0; i < size; i++) {
            str.append(getCharacters());
        }
        return str.toString();
    }
    
    // --------------------------- 随机生成 end ---------------------------
    
    // ---------------------------- 排序 start ----------------------------
    
    // ---------------------------- 排序 start ----------------------------
    
}
